package xyz.esion.knowledgebase.service.impl

import cn.hutool.core.util.StrUtil
import org.springframework.stereotype.Service
import xyz.esion.knowledgebase.domain.ArticleInfo
import xyz.esion.knowledgebase.domain.ArticleTree
import xyz.esion.knowledgebase.entity.article.ArticleBase
import xyz.esion.knowledgebase.entity.article.ArticleFolder
import xyz.esion.knowledgebase.entity.article.ArticleIndex
import xyz.esion.knowledgebase.repository.ArticleBaseRepository
import xyz.esion.knowledgebase.repository.ArticleFolderRepository
import xyz.esion.knowledgebase.repository.ArticleIndexRepository
import xyz.esion.knowledgebase.service.ArticleService
import xyz.esion.knowledgebase.util.listToTree

/**
 * @author Esion
 * @since 2024/1/23
 */
@Service
class ArticleServiceImpl(
    private val folderRepository: ArticleFolderRepository,
    private val indexRepository: ArticleIndexRepository,
    private val baseRepository: ArticleBaseRepository
) : ArticleService {

    override fun tree(title: String): List<ArticleTree> {
        // 获取全部合适的文章
        val articles = if (StrUtil.isEmpty(title)) {
            indexRepository.findAll()
        } else {
            indexRepository.findByNameContainingIgnoreCase(title)
        }
        // 根据文章查询所有的目录
        val folders = findFolders(articles)
        return listToTree(folders, articles)
    }

    override fun info(id: Int): ArticleInfo {
        // 查询索引
        val index = indexRepository.findById(id).orElseThrow { IllegalArgumentException("文章 $id 不存在") }
        val base = baseRepository.findById(id).orElse(ArticleBase())
        return ArticleInfo(index, base)
    }

    private fun findFolders(articles: List<ArticleIndex>): List<ArticleFolder> {
        var folderIds = articles.map { e -> e.folder }.toList()
        val folders = ArrayList<ArticleFolder>()
        while (folderIds.isNotEmpty()) {
            val templates = folderRepository.findAllById(folderIds)
            folders.addAll(templates)
            folderIds = templates.map { e -> e.pid }
                .filter { e -> e > 0 }
                .toList()
        }
        return folders
    }

}